﻿/*
 * 封装了一些常用的COM命令
 * 褚迪   2017-8-22
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;

namespace Genesis
{
    
    public class gCOM :gGetInfo
    {
       
        /// <summary>
        /// 设置单位，默认为mm
        /// </summary>
        /// <param name="u"></param>
        public void unit(string u = "mm")
        { 
             COM("units", "type=" + u);
        }

        public void save_job(string job,string Override = "no" )
        {
            COM( "save_job", $"job={job},override={Override}");
        }
        public void output_layer_reset( )
        {
            COM( "output_layer_reset" );
        }

        public void output_layer_set( string layer,int angle,string mirror,double x_scale,double y_scale,int comp=0,string polarity="positive",string setupfile="",string setupfiletmp="",string line_units="inch",string gscl_file = "" )
        {
            COM( "output_layer_set",
                $"layer={layer},angle={angle},mirror={mirror},x_scale={x_scale},y_scale={y_scale},comp={comp},polarity={polarity},setupfile={setupfile},setupfiletmp={setupfiletmp},line_units={line_units},gscl_file={gscl_file}");
        }

        public void output(string job,string step,string dir_path,string format="Gerber274x", string prefix="",string suffix="",string break_sr="yes",string break_symbols ="yes",string break_arc="yes",string scale_mode="all",string surface_mode="contor",int min_brush=1,
            string units="inch",string coordinates="absolute",string zeroes="leading",
            int nf1=2,int nf2=6,int x_anchor=0,int y_anchor=0,string wheel="",
            int x_offset=0,int y_offset=0,string line_units="inch",string override_online="yes",
            int film_size_cross_scan=0,int film_size_along_scan=0,string ds_model="RG6500")
        {
            string command =
                $"job={job},step={step},format={format},dir_path={dir_path},prefix={prefix},suffix={suffix},break_sr={break_sr},break_symbols={break_symbols},break_arc={break_arc},scale_mode={scale_mode},surface_mode={surface_mode},min_brush={min_brush},units={units},coordinates={coordinates},zeroes={zeroes},nf1={nf1},nf2={nf2},x_anchor={x_anchor},y_anchor={y_anchor},wheel={wheel},x_offset={x_offset},y_offset={y_offset},line_units={line_units},override_online={override_online},film_size_cross_scan={film_size_cross_scan},film_size_along_scan={film_size_along_scan},ds_model={ds_model}";
            COM("output", command);
        }
        public void export_job( string job,string path,string mode ="tar_gzip",string submode="full",string overwrite = "yes" )
        {
            COM( "export_job", $"job={job},path={path},mode={mode},submode={submode},overwrite={overwrite}");

        }
   

        public void Set_units(string units = "mm")
        {
            COM("units", "type=" + units);
        }

        public void undo()
        {
            COM("undo");
        }

        public void editor_page_close()
        {
            COM("editor_page_close");
        }

        public void sel_single_feat(PointF point,string operation="select",string tol="100",string cyclic="no")
        {
            COM("sel_single_feat", $"operation={operation},x={point.X.ToString()},y={point.Y.ToString()},tol={tol},cyclic={cyclic}");
        }

        public void sel_intersect_coord(double dj, string mode = "round")
        {
            COM("sel_intersect_coord", "function=find_connect", "mode=" + mode, "radius=" + dj.ToString(), "length_x=0", "length_y=0", "type_x=length", "type_y=length", "show_all=no", "keep_remainder1=no", "keep_remainder2=no", "ang_x=0", "ang_y=0");
        }

        public object get_select_counts()
        {
            COM("get_select_count");
            return (object)COMANS;
        }

        public void sel_move_other(string target_layer="", string invert= "no", int dx= 0, int dy = 0, double size= 0, double x_anchor= 0,double y_anchor= 0,double rotation= 0,string mirror= "none")
        {
            COM("sel_move_other",
           $"target_layer={target_layer},invert={invert},dx={dx.ToString()},dy={dy.ToString()},size={size.ToString()},x_anchor={x_anchor.ToString()},y_anchor={y_anchor.ToString()},rotation={rotation.ToString()},mirror={mirror}");
        }

        public void sel_ref_feat(string layers= "", string use = "filter", string mode ="disjoint", string pads_as = "shape", string f_types = "line;pad;surface;arc;text", string polarity = "positive;negative",string include_syms = "", string exclude_syms = "")
        {
            COM("sel_ref_feat", $"layers={layers},use={use},mode={mode},pads_as={pads_as},f_types={f_types},polarity={polarity},include_syms={include_syms},exclude_syms={exclude_syms}");
        }
        public void sel_copy_other(string dest= "layer_name",string target_layer= "",string invert= "no",double dx= 0, double dy = 0, double size = 0, double x_anchor = 0, double y_anchor = 0, double rotation = 0,string mirror= "none")
        {
            COM("sel_copy_other",$"dest={dest},target_layer={target_layer},invert={invert},dx={dx.ToString()},dy={dy.ToString()},size={size.ToString()},x_anchor={x_anchor.ToString()},y_anchor={y_anchor.ToString()},rotation={rotation.ToString()},mirror={mirror}");

        }
        public void sel_contourize(double accuracy= 6.35,string break_to_islands= "yes",double clean_hole_size= 76.2,string clean_hole_mode= "x_and_y")
        {
            COM("sel_contourize", $"accuracy={accuracy.ToString()},break_to_islands={break_to_islands},clean_hole_size={clean_hole_size.ToString()},clean_hole_mode={clean_hole_mode}");

        }
        public void fill_params(string type= "solid", string origin_type = "datum", string solid_type = "fill", string std_type = "line",double min_brush= 150, string use_arcs= "yes", string symbol = "",double dx= 2.54,double dy= 2.54,
               double x_off= 0, double y_off = 0, double std_angle = 45, double std_line_width = 254, double std_step_dist = 1270,string std_indent= "odd", string break_partial= "yes",string cut_prims= "no", string outline_draw = "no",double outline_width= 0,string outline_invert= "no")
        {
            COM("fill_params", $"type={type}," +
                $"origin_type={origin_type}," +
                $"solid_type={solid_type}," +
                $"std_type={std_type}," +
                $"min_brush={min_brush.ToString()}," +
                $"use_arcs={use_arcs}," +
                $"symbol={symbol}," +
                $"dx={dx.ToString()}," +
                $"dy={dy.ToString()}," +
                $"x_off={x_off.ToString()}," +
                $"y_off={y_off.ToString()}," +
                $"std_angle={std_angle.ToString()}," +
                $"std_line_width={std_line_width.ToString()}," +
                $"std_step_dist={std_step_dist.ToString()}," +
                $"std_indent={std_indent}," +
                $"break_partial={break_partial}," +
                $"cut_prims={cut_prims}," +
                $"outline_draw={outline_draw}," +
                $"outline_width={outline_width.ToString()}," +
                $"outline_invert={outline_invert.ToString()}");
       
        }

        public void sel_fill()
        {
            COM("sel_fill");
        }
        

        public void filter_select(string symbols, string layer = "")
        {
            COM("filter_set", "filter_name=popup", "update_popup=no", "include_syms=" + symbols);
            COM("filter_area_strt");
            COM("filter_area_end", "layer=" + layer, "filter_name=popup", "operation=select", "area_type=none", "inside_area=no", "intersect_area=no");
        }

        public void filter_area_strt()
        {
            COM("filter_area_strt");
        }

        public void filter_area_end(string layer = "", string operation = "select")
        {
            COM("filter_area_end", "layer=" + layer, "filter_name=popup", "operation=" + operation, "area_type=none", "inside_area=no", "intersect_area=no", "min_len=0", "max_len=0", "min_angle=0", "max_angle=0");
        }

        public void filter_reset(string filter_name= "popup")
        {
            COM("filter_reset", $"filter_name={filter_name}");
        }

        public void filter_atr_reset()
        {
            COM("filter_atr_reset");
        }
        public void add_pad(string symbol, double x, double y, string attributes="no",string polarity= "positive",
            double angel=0,string mirror="no",int nx=1,int ny=1,double dx=0,double dy=0,double xscale=1,double yscale = 1)
        {
            COM("add_pad", $"attributes={attributes},x={x.ToString()},y={y.ToString()},symbol={symbol},polarity={polarity},angle={angel.ToString()},mirror={mirror},nx={nx.ToString()},ny={ny.ToString()},dx={dx.ToString()},dy={dy.ToString()},xscale={xscale.ToString()},yscale={yscale.ToString()}");
        }

        /// <summary>
        /// 添加线，symbol默认为r150，公制
        /// </summary>
        /// <param name="xs"></param>
        /// xs为起点X坐标
        /// <param name="ys"></param>
        /// ys为起点Y坐标
        /// <param name="xe"></param>
        /// xe为终点X坐标
        /// <param name="ye"></param>
        /// ye为重点Y坐标
        /// <param name="symbol"></param>
        /// <param name="polarity"></param>
        public void add_line(double xs, double ys, double xe, double ye, string symbol = "r150", string polarity = "positive")
        {
            COM("add_line", "attributes=no", "xs=" +xs.ToString(), "ys =" +ys.ToString(), "xe=" +xe.ToString(), "ye=" +ye.ToString(), "symbol=" + symbol, "polarity=" + polarity);
        }




        /// <summary>创建profile</summary>
        public void profile_rect(double x1, double y1, double x2, double y2)
        {
            COM("profile_rect", "x1=" + x1.ToString(), "y1=" + y1.ToString(), "x2=" + x2.ToString(), "y2=" + y2.ToString());
        }


       
        /// <summary>
        /// 第一个参数为symbol
        /// 第二个参数为需要添加多边形的点的数组，其中数组的第一个值应为原点
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="points"></param>
        public void add_polyline(string symbol, params PointF []points)
        {
            //第一个点为原点
            PointF point1 = points[0];
            COM("add_polyline_strt");
            COM("add_polyline_xy", "x=" + point1.X.ToString(), "y=" + point1.Y.ToString());
            for(int i = 1; i < points.Count(); i++)
            {
                COM("add_polyline_xy", "x=" + points[i].X.ToString(), "y=" + points[i].Y.ToString());
            }
            //最后回归原点
            COM("add_polyline_xy", "x=" + point1.X.ToString(), "y=" + point1.Y.ToString());
            COM("add_polyline_end", "attributes=no", " symbol=" + symbol, " polarity=positive");
        }

        /// <summary>
        /// 添加正方形
        /// </summary>
        /// <param name="orig"></param>
        /// <param name="sizes"></param>
        /// <param name="symbol"></param>
        public void add_polyline_rect(PointF orig, SizeF sizes, string symbol)
        {
            PointF point1 = orig;
            PointF point2 = new PointF();
            PointF point3 = new PointF();
            PointF point4 = new PointF();

            point2.X = orig.X + sizes.Width;
            point2.Y = orig.Y;
            point3.X = orig.X + sizes.Width;
            point3.Y = orig.Y + sizes.Height;
            point4.X = orig.X;
            point4.Y = orig.Y + sizes.Height;

            this.add_polyline(symbol ,point1, point2, point3, point4);
        }


        /// <summary>显示层</summary>
        /// <param name="layers">需要显示的层名</param>
        /// <param name="display">yes/no</param>
        /// <param name="number">显示序号，最大4</param>
        public void display_layer(string layers, string display = "yes", int number = 1)
        {
            COM("display_layer", "name=" + layers, "display=" + display, "number=" + number.ToString());
        }

        /// <summary>设置工作层</summary>
        public void work_layer(string layer)
        {
            COM("work_layer", "name=" + layer);
        }


        public void delete_layer(string layer)
        {
            COM("delete_layer", "layer=" + layer);
        }

        public void copyLayer2other(string targetLayer, string dest = "layer_name", string invert = "no", double dx = 0.0, double dy = 0.0, double size = 0.0, double x_anchor = 0.0, double y_anchor = 0.0, double rotation = 0.0, string mirror = "none")
        {
            COM("sel_copy_other", "dest=" + dest, "target_layer=" + targetLayer, "invert=" + invert, "dx=" +dx.ToString(), "dy=" +dy.ToString(), "size=" +size.ToString(), "x_anchor=" +x_anchor.ToString(), "y_anchor=" +y_anchor.ToString(), "rotation=" +rotation.ToString(), "mirror=" + mirror);
        }

        /// <summary>打开实体</summary>
        public void open_entity(string JOB, string stepname)
        {
            COM("open_entity", "job  =" + JOB, "type=step", "name=" + stepname, "iconic =no");
            AUX("set_group", "group=" + COMANS);
        }

        public void affected_layer(string layer, string mode = "single", string affected = "yes")
        {
            COM("affected_layer", "name=" + layer, "mode=" + mode, "affected=" + affected);
        }

        public void create_layer(string layer, string ins_layer = "", string context = "misc", string type = "signal", string polarity = "positive")
        {
            COM("create_layer", "layer=" + layer, "context=" + context, "Type=" + type, "polarity=" + polarity, "ins_layer=" + ins_layer);
        }

        /// <summary>创建实体</summary>
        /// <param name="JOB">料号</param>
        /// <param name="stepname">STEP名</param>
        public void create_entity(string JOB, string stepname)
        {
            COM("create_entity", "job=" + JOB, "is_fw=no", "type=step", "name=" + stepname, "db=genesis", "fw_type=form");
        }

        /// <summary>创建虚拟拼版</summary>
        public void str_tab_add(string stepname, double x, double y, int nx, int ny, double dx, double dy, double angle = 0.0, string mirror = "no")
        {
            COM("sr_tab_add", "line=1", "step=" + stepname, "x=" +x.ToString(), "y=" +y.ToString(), "nx=" +nx.ToString(), "ny=" +ny.ToString(), "dx=" +dx.ToString(), "dy=" +dy.ToString(), "angle=" +angle.ToString(), "mirror=" + mirror);
        }
        public void chklist_single(string action= "valor_dfm_sigopt",string show = "yes")
        {
            COM("chklist_single", $"action={action}, show={show}");
        }

        public void chklist_cupd(string pp_layer, string pp_pth_ar,string pp_via_ar)
        {
            COM ("chklist_cupd", $"chklist = valor_dfm_sigopt, nact = 1,params= ((pp_layer = {pp_layer})(pp_min_pth_ar = {pp_pth_ar})(pp_opt_pth_ar = {pp_pth_ar})(pp_min_via_ar = {pp_via_ar})(pp_opt_via_ar = {pp_via_ar})(pp_min_microvia_ar = 0)(pp_opt_microvia_ar = 0)(pp_min_spacing = 2.54)(pp_opt_spacing = 2.54)(pp_min_p2p_spacing = 2.54)(pp_opt_p2p_spacing = 2.54)(pp_min_line = 101.6)(pp_opt_line = 254)(pp_nd_percent = 10)(pp_abs_min_line = 127)(pp_min_pth2c = 101.6)(pp_selected = All)(pp_work_on = Pads\\; SMDs\\; Drills)(pp_modification = PadUp)),mode = regular");
        }

        public void chklist_run()
        {
            COM("chklist_run", "chklist = valor_dfm_sigopt, nact = 1, area = profile");
        }

        public void disp_on()
        {
            COM("disp_on");
        }
        public void origin_on()
        {
            COM("origin_on");
        }
       



    }
}
